﻿namespace EFML_Runtime
{
    using System.Collections.Generic;
    using System.IO;
    using System.IO.Compression;

    public class Exeutable
    {
        #region Fields

        public List<string> Components = new List<string>();

        public ApplicationInfo Info = new ApplicationInfo();

        public bool IsComponent;

        public string MainForm;

        public Dictionary<string, byte[]> Resources = new Dictionary<string, byte[]>();

        public Dictionary<string, string> Sources = new Dictionary<string, string>();

        public Dictionary<string, string> Strings = new Dictionary<string, string>();

        #endregion

        #region Public Properties

        public string RuntimeVersion
        {
            get
            {
                return "0.0.0.1";
            }
        }

        #endregion

        #region Public Methods and Operators

        public void Load(Stream s)
        {
            var r = new BinaryReader(new GZipStream(s, CompressionMode.Decompress));
            if (r.ReadString() == "IFEM")
            {
                this.Info.ApplicationName = r.ReadString();
                this.Info.Author = r.ReadString();
                this.Info.Copyright = r.ReadString();
                this.Info.Description = r.ReadString();
                this.Info.Website = r.ReadString();
                this.Info.Version = r.ReadString();

                this.MainForm = r.ReadString();

                int sc = r.ReadInt32();
                for (int i = 0; i < sc; i++)
                {
                    this.Strings.Add(r.ReadString(), r.ReadString());
                }

                int sL = r.ReadInt32();
                var sTr = new Dictionary<string, string>();
                for (int i = 0; i < sL; i++)
                {
                    sTr.Add(r.ReadString(), r.ReadString());
                }
                this.Sources = sTr;

                this.IsComponent = r.ReadBoolean();
                int ci = r.ReadInt32();
                for (int i = 0; i < ci; i++)
                {
                    this.Components.Add(r.ReadString());
                }

                int iL = r.ReadInt32();
                var ir = new List<byte>();
                for (int i = 0; i < iL; i++)
                {
                    ir.Add(r.ReadByte());
                }
                this.Info.Icon = ir.ToArray();

                int rL = r.ReadInt32();
                var rr = new Dictionary<string, byte[]>();
                for (int i = 0; i < rL; i++)
                {
                    string nam = r.ReadString();
                    var bytes = new List<byte>();
                    int bl = r.ReadInt32();
                    for (int j = 0; j < bl; j++)
                    {
                        bytes.Add(r.ReadByte());
                    }
                    rr.Add(nam, bytes.ToArray());
                }
                this.Resources = rr;

                r.Close();
            }
        }

        public void Save(Stream s)
        {
            var w = new BinaryWriter(new GZipStream(s, CompressionMode.Compress));
            w.Write("IFEM");

            // Application Info
            w.Write(this.Info.ApplicationName);
            w.Write(this.Info.Author);
            w.Write(this.Info.Copyright);
            w.Write(this.Info.Description);
            w.Write(this.Info.Website);
            w.Write(this.Info.Version);

            w.Write(this.MainForm);

            w.Write(this.Strings.Count);
            foreach (var s1 in this.Strings)
            {
                w.Write(s1.Key);
                w.Write(s1.Value);
            }

            w.Flush();

            w.Write(this.Sources.Count);
            foreach (var source in this.Sources)
            {
                w.Write(source.Key);
                w.Write(source.Value);
            }

            w.Write(this.IsComponent);

            w.Write(this.Components.Count);
            foreach (var component in this.Components)
            {
                w.Write(component);
            }

            w.Write(this.Info.Icon.Length);
            foreach (var b in this.Info.Icon)
            {
                w.Write(b);
            }

            w.Flush();

            w.Write(this.Resources.Count);
            foreach (var resource in this.Resources)
            {
                w.Write(resource.Key);
                w.Write(resource.Value.Length);
                foreach (var b in resource.Value)
                {
                    w.Write(b);
                }
            }

            w.Flush();
            w.Close();
        }

        #endregion
    }
}